package com.xishu.controller;

import com.xishu.annotation.valid.MethodValidator;
import com.xishu.config.Config;
import com.xishu.config.Constant;
import com.xishu.entity.shop.PayType;
import com.xishu.entity.shop.Shop;
import com.xishu.entity.shop.TakeOutSetting;
import com.xishu.exception.ResponseStatusException;
import com.xishu.response.ResponseData;
import com.xishu.response.ResponseStatus;
import com.xishu.response.VerifyUtil;
import com.xishu.service.*;
import com.xishu.util.Tools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

import java.util.List;
import java.util.OptionalInt;
import java.util.stream.Collectors;

import static com.xishu.config.Constant.*;
import static com.xishu.response.ResponseStatus.CAN_NOT_DELETE_PAY_TYPE_WHEN_SHOP_ONLINE;

@RestController
@Api(description = "支付方式管理")
public class PayTypeController implements Tools {
    @ApiOperation(value = "创建支付方式")
    @PostMapping(value = ("/pay/type"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShopId = true)
    public ResponseData create(@RequestBody PayType payType) throws Exception {
        VerifyUtil.verify(() -> payType.getShopId() != null);
        Long shopId = payType.getShopId();
        Shop shop = ShopService.getInstance().findShopById(shopId);
        payType.setCompanyId(shop.getCompanyId());
        ZhEnService.getInstance().dealZhEn(payType);
        payType.setRuntimeVersion(Config.getInstance().getDolaVersion());

        //创建的时候，增加type值
        List<PayType> payTypeList = PayTypeService.getInstance().findPayTypeList(shopId);
        OptionalInt max = payTypeList.stream().mapToInt(p -> getInt(p.getType())).max();

        //从13开始
        if (max.isPresent()) {
            payType.setType(Math.max(13, max.getAsInt()) + 1);
        } else {
            //报错
            VerifyUtil.throwError(ResponseStatus.SYSTEM_ERROR);
        }

        ResponseData responseData = CommonService.getInstance().createObject(payType);
        PayTypeService.getInstance().flushPayTypeListCash(shopId);
        return responseData;
    }

    @ApiOperation(value = "修改支付方式")
    @PutMapping(value = ("/pay/type/modify"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true)
    public ResponseData modify(@RequestBody PayType payType) throws Exception {
        ResponseData responseData = CommonService.getInstance().updateObject(payType);
        PayType payTypeInDb = CommonService.getInstance().findEntity(payType.id, PayType.class);
        //重新查询
        PayTypeService.getInstance().flushPayTypeListCash(payTypeInDb.getShopId());
        return responseData;
    }

    @ApiOperation(value = "查询支付方式,如果没有默认值，则创建")
    @PutMapping(value = ("/pay/type"), produces = ("application/json;charset=UTF-8"))
    public ResponseData search(@RequestBody PayType payType) throws Exception {
        Long shopId = payType.getShopId();
        payType.setRuntimeVersion(Config.getInstance().getDolaVersion());

        if (shopId != null) {
            Object lock = LockService.getInstance().getLock("pay.type" + shopId);

            synchronized (lock) {
                Shop shop = ShopService.getInstance().findShopById(shopId);

                if (!getBoolean(shop.getInitPayType())) {
                    PayTypeService.getInstance().createDefaultPayType(shopId);
                    shop.setInitPayType(true);
                    CommonService.getInstance().save(shop);
                }
            }
        }

        return CommonService.getInstance().searchResponse(payType);
    }

    @ApiOperation(value = "删除支付方式")
    @DeleteMapping(value = ("/pay/type"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true)
    public ResponseData delete(@RequestBody PayType payType) throws Exception {
        //如果是默认的支付方式，不能删除
        PayType payTypeInDb = CommonService.getInstance().findEntity(payType.getId(), PayType.class);
        VerifyUtil.verify(() -> !getBoolean(payTypeInDb.getDefaultType()));

        //正在营业的时候，不能删除
        Long shopId = payTypeInDb.getShopId();
        Shop shop = ShopService.getInstance().findShopById(shopId);
        VerifyUtil.verify(() -> !getBoolean(shop.getBusinessStatus()), CAN_NOT_DELETE_PAY_TYPE_WHEN_SHOP_ONLINE);

        ResponseData responseData = CommonService.getInstance().delete(payType);
        //重新查询
        PayTypeService.getInstance().flushPayTypeListCash(shopId);

        //将外卖设定里面的支付方式清空
        List<TakeOutSetting> takeOutSettingList = TakeOutSettingService.getInstance().findTakeAwaySetting(payTypeInDb.getShopId());
        takeOutSettingList = takeOutSettingList.stream().filter(p -> equals(p.getPayTypeId(), payTypeInDb.getId())).collect(Collectors.toList());

        for (TakeOutSetting takeOutSetting : takeOutSettingList) {
            takeOutSetting.setPayTypeId(null);
            CommonService.getInstance().save(takeOutSetting);
        }

        return responseData;
    }

    @ApiOperation(value = "查询外卖配置对应的支付方式")
    @PutMapping(value = ("/pay/type/for/take/out"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true)
    public ResponseData queryTakeoutConfig(@RequestBody PayType payType) throws Exception {
        Long shopId = payType.getShopId();
        VerifyUtil.verify(() -> shopId != null);

        List<PayType> payTypeList = PayTypeService.getInstance().findPayTypeListCache(shopId);
        payTypeList = payTypeList.stream().filter(p -> p.getType() != ORDER_PAY_TYPE_CASH).filter(p -> p.getType() != ORDER_PAY_TYPE_STRIPE).collect(Collectors.toList());

        //过滤是否已经配置了qfcode
        boolean qfConfig = PayTypeService.getInstance().isQfConfig(shopId);

        //如果配置了qf,那么不能够配置微信和支付宝
        if (qfConfig) {
            payTypeList = payTypeList.stream().filter(p -> p.getType() != ORDER_PAY_TYPE_WEIXIN).filter(p -> p.getType() != ORDER_PAY_TYPE_ALIPAY).collect(Collectors.toList());
        }

        //过滤已上线的支付方式
        if (getBoolean(payType.getEnable())) {
            payTypeList = payTypeList.stream().filter(p -> getBoolean(p.getEnable())).collect(Collectors.toList());
        }

        return CommonService.getInstance().createResponse(payTypeList);
    }

    @ApiOperation(value = "查询支付方式,配置并开启了第三方，就不显示支付宝和微信")
    @PutMapping(value = ("/pay/type/non/third/party"), produces = ("application/json;charset=UTF-8"))
    public ResponseData searchThirdParty(@RequestBody PayType payType) throws Exception {
        VerifyUtil.verify(() -> payType.getShopId() != null);
        ShopService shopService = ShopService.getInstance();
        List<PayType> payTypeListInDb = PayTypeService.getInstance().findPayTypeList(payType.getShopId());
        //过滤掉未启动的支付类型
        List<PayType> payTypeList = payTypeListInDb.stream().filter(PayType::getEnable).collect(Collectors.toList());
        Shop shopInDb = shopService.findShopById(payType.getShopId());
        //已启动但又包含微信和支付宝
        boolean include = payTypeList.stream().anyMatch(t -> t.getType() == Constant.PAY_TYPE_WEIXIN || t.getType() == Constant.PAY_TYPE_ALI_PAY);
        //如果配置了并且也启动了任意一个第三方支付，就过滤掉支付宝和微信
        if (include) {
            //设置是否有配置好支付
            shopService.setPayFlag(shopInDb);
            if (getBoolean(shopInDb.getQfComplete())) {
                //过滤微信和支付宝
                payTypeList = payTypeList.stream().filter(t -> t.getType() != Constant.PAY_TYPE_WEIXIN && t.getType() != Constant.PAY_TYPE_ALI_PAY).collect(Collectors.toList());
            }
        }
        return CommonService.getInstance().createResponse(payTypeList);
    }

}
